package com.wmh.baseservice.robot.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wmh.baseservice.common.ex.ServiceException;
import com.wmh.baseservice.common.mybatisplus.structure.LambdaQueryWrapperX;
import com.wmh.baseservice.common.utils.web.UserUtil;
import com.wmh.baseservice.robot.convert.RobotTaskAdPushUnitConvert;
import com.wmh.baseservice.robot.entity.RobotInfo;
import com.wmh.baseservice.robot.entity.RobotRes;
import com.wmh.baseservice.robot.entity.RobotTaskAdPushUnit;
import com.wmh.baseservice.robot.enums.RobotPushTaskType;
import com.wmh.baseservice.robot.enums.RobotStatusEnums;
import com.wmh.baseservice.robot.mapper.RobotTaskAdPushUnitMapper;
import com.wmh.baseservice.robot.pojo.dto.robottaskadpushunit.RobotTaskAdPushUnitPushReqVO;
import com.wmh.baseservice.robot.pojo.vo.robottaskadpushunit.RobotTaskAdPushUnitCreateReqVO;
import com.wmh.baseservice.robot.pojo.vo.robottaskadpushunit.RobotTaskAdPushUnitPushTaskReqVO;
import com.wmh.baseservice.robot.pojo.vo.robottaskadpushunit.RobotTaskAdPushUnitUpdateReqVO;
import com.wmh.baseservice.robot.service.RobotInfoService;
import com.wmh.baseservice.robot.service.RobotTaskAdPushUnitService;
import com.wmh.baseservice.robot.service.RobotTaskService;
import com.wmh.baseservice.robot.service.RobotTaskStatementV2Service;
import com.wmh.baseservice.robot.tools.MyHttpUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 谢骏
 * @description 针对表【robot_task_ad_push_unit(自动化机器-管理员发布任务单元)】的数据库操作Service实现
 * @createDate 2023-09-07 14:22:21
 */
@Service
public class RobotTaskAdPushUnitServiceImpl extends ServiceImpl<RobotTaskAdPushUnitMapper, RobotTaskAdPushUnit>
        implements RobotTaskAdPushUnitService {

    @Resource
    private UserUtil userUtil;

    @Resource
    private MyHttpUtil myHttpUtil;

    @Resource
    private RobotInfoService robotInfoService;

    @Resource
    private RobotTaskService robotTaskService;

    @Resource
    private RobotTaskStatementV2Service robotTaskStatementV2Service;

    @Override
    public void create(RobotTaskAdPushUnitCreateReqVO reqVO) {
        checkNameUnique(null, reqVO.getName());
        baseMapper.insert(RobotTaskAdPushUnitConvert.INSTANCE.convert(reqVO, userUtil.getId()));
    }

    @Override
    public void update(RobotTaskAdPushUnitUpdateReqVO reqVO) {
        checkExists(reqVO.getId());
        checkNameUnique(reqVO.getId(), reqVO.getName());
        baseMapper.updateById(RobotTaskAdPushUnitConvert.INSTANCE.convert(reqVO, userUtil.getId()));
    }

    @Override
    public String getParam(Long id) {
        RobotTaskAdPushUnit entity = baseMapper.selectById(id);
        if (entity == null) {
            return null;
        }
        return entity.getParam();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pushTask(RobotTaskAdPushUnitPushTaskReqVO reqVO) {
        List<RobotInfo> robotList = robotInfoService.listByIds(reqVO.getRobotNumberList());
        if (robotList.isEmpty() || robotList.size() != reqVO.getRobotNumberList().size()) {
            throw new ServiceException("发布任务失败, 获取机器时异常");
        }
        // 发布任务单元列表
        List<RobotTaskAdPushUnit> unitList = listByIds(reqVO.getPushUnitIds());
        // 获取发布单元对应的任务名称与主键的映射 方便获取任务名称
        Map<Long, String> nameMap = robotTaskService.getIdNameMap(CollUtil.map(unitList, RobotTaskAdPushUnit::getRobotTaskId, true));
        // 接收失败机器编号
        ArrayList<Long> errIdList = new ArrayList<>();
        for (RobotInfo robot : robotList) {
            // 构建发布任务对象
            RobotTaskAdPushUnitPushReqVO reqObj = RobotTaskAdPushUnitConvert.INSTANCE.convert1(unitList, nameMap, userUtil.get(), reqVO.getIsTest(), RobotPushTaskType.NORMAL.getValue());
            // 发布任务
            RobotRes res = myHttpUtil.post(robot, "接收任务", JSON.parseObject(JSON.toJSONString(reqObj)));
            // 成功
            if (RobotRes.isSuccess(res)) {
                robot.setStatusId(RobotStatusEnums.RUNNING.getId());
                // 初始化报表
                robotTaskStatementV2Service.create(reqObj, robot);
            }
            // 失败
            else {
                robot.setStatusId(RobotStatusEnums.LOST_CONNECTION.getId());
                errIdList.add(robot.getRobotNumber());
            }
        }
        if (CollUtil.isNotEmpty(errIdList)) {
            throw new ServiceException(StrUtil.format("机器接收任务失败,相关机器编号 : {}", errIdList.toString()));
        }
        // 更新机器信息
        robotInfoService.saveOrUpdateBatch(robotList);
    }

    private void checkNameUnique(Long id, String name) {
        RobotTaskAdPushUnit entity = baseMapper.selectOne(new LambdaQueryWrapperX<RobotTaskAdPushUnit>()
                .eq(RobotTaskAdPushUnit::getName, name)
                .neIfPresent(RobotTaskAdPushUnit::getId, id)
                .eq(RobotTaskAdPushUnit::getAdId, userUtil.getId()));
        if (entity != null) {
            throw new ServiceException("该名称已经被使用");
        }
    }

    private void checkExists(Long id) {
        if (baseMapper.selectById(id) == null) {
            throw new ServiceException("数据已不存在");
        }
    }
}




